package com.guoxue.action.front;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.guoxue.consts.CUser;
import com.guoxue.consts.SCUser;
import com.guoxue.domain.FollowsVo;
import com.guoxue.domain.TotalInfoVo;
import com.guoxue.domain.UserVo;
import com.guoxue.service.IFollowsService;
import com.guoxue.service.ITotalInfoService;
import com.guoxue.service.IUserService;
import com.guoxue.util.ChatUtils;
import com.guoxue.util.LoggerUtil;
import com.guoxue.util.OSSUtil;
import com.guoxue.util.codeSwitch.zt;

@Controller
@RequestMapping("User")
/**
 * 用户好友处理接口，主要包括： 1.follows添加好友（关注） 2.cancelFollowed删除好友（关注） 3.putBlack加入黑名单
 * 4.cancelBlack修改好友（解除黑名单） 5.getBlackList查询黑名单列表 6.checkFollowed查询是否是好友
 * 
 * @author kanghb
 */
public class FollowsAction extends BaseAction {
	@Resource
	private IFollowsService followsService;
	@Resource
	private IUserService userService;
	@Resource
	private ITotalInfoService totalInfoService;
	@Resource
	private OSSUtil oss;

	/**
	 * 解除拉黑(恢复陌生人身份)接口
	 * 
	 * @param req
	 * @param resp
	 * @param uid_target
	 *            被拉黑者id
	 * @return
	 */
	@RequestMapping("/cancelBlacker")
	@ResponseBody
	public JSON A1_cancelBlacker(HttpServletRequest req, HttpServletResponse resp, Integer uid_target) {
		final int uid_this = SCUser.getUidFromReq(req);
		FollowsVo followsVo_target, followsVo_this;

		// 参数基本检查:
		if (uid_target == null || uid_target < CUser.MIN_USER_ID || uid_target == uid_this) {
			return Message(ERROR, "目标用户id错误", null);
		}
		followsVo_this = followsService.getFriendByIdAllStatus(uid_target, uid_this);
		// 检查自己是否已拉黑了对方:
		if (followsVo_this == null || (followsVo_this.getSysflag() != 3)) {
			// return Message(ERROR, "该用户没有被拉黑", null);
			return Message(SUCCESS, "解除拉黑成功", null);
		}

		/////////////////////// 至此,已通过了所有检查,开始修改数据:
		// 修改followsVo数据:
		zt.tb.question(); // 改为直接删除该数据?
		followsVo_this.setSysflag(1); // sysflag等于1,相当于陌生人
		followsService.saveFollows(followsVo_this);
		return Message(SUCCESS, "解除拉黑成功", null);
	}

	/**
	 * 取消关注(删除好友)接口
	 * 
	 * @param req
	 * @param resp
	 * @param uid_target
	 *            被关注的好友id
	 * @return
	 */
	@RequestMapping("/cancelFriend")
	@ResponseBody
	public JSON A1_cancelFriend(HttpServletRequest req, HttpServletResponse resp, Integer uid_target) {
		final int uid_this = SCUser.getUidFromReq(req);
		FollowsVo followsVo_target, followsVo_this;

		// 参数基本检查:
		if (uid_target == null || uid_target < CUser.MIN_USER_ID) {
			return Message(ERROR, "目标用户id错误", null);
		}
		if (uid_target == uid_this) {
			return Message(ERROR, "不能自己拉黑自己", null);
		}

		followsVo_this = followsService.getFriendByIdAllStatus(uid_target, uid_this);
		// 检查自己是否已关注了对方:
		if (followsVo_this == null || (followsVo_this.getSysflag() != 0)) {
			// return Message(ERROR, "不存在该关注", null);
			return Message(SUCCESS, "取消关注成功", null);
		}

		/////////////////////// 至此,已通过了所有检查,开始修改数据:
		// 修改followsVo数据:
		zt.tb.question(); // 改为直接删除该数据?
		followsVo_this.setSysflag(1); // sysflag等于1,相当于陌生人
		followsService.saveFollows(followsVo_this);

		// 维护关注和被关注的总计数:
		zt.tb.function(); // 将用户的好友数据缓存在内存中,去掉TotalInfoVo中的Follow字段和BeFollowed字段(不需要再维护了!)
		{
			// 维护uid_this的TotalInfoVo的Follow字段:
			TotalInfoVo totalInfoVo_this = totalInfoService.getInfoByUid(uid_this);
			totalInfoVo_this.setFollow(totalInfoVo_this.getFollow() - 1);
			totalInfoService.saveOrUpateInfo(totalInfoVo_this);
			// 维护uid_target的TotalInfoVo的BeFollowed字段:
			TotalInfoVo totalInfoVo_target = totalInfoService.getInfoByUid(uid_target);
			totalInfoVo_target.setBeFollowed(totalInfoVo_target.getBeFollowed() - 1);
			totalInfoService.saveOrUpateInfo(totalInfoVo_target);
		}

		return Message(SUCCESS, "取消关注成功", null);
	}

	/**
	 * 拉黑(添加黑名单成员)
	 * 
	 * @param req
	 * @param resp
	 * @param uid_target
	 *            被拉黑者id
	 * @return
	 */
	@RequestMapping("/addBlacker")
	@ResponseBody
	public JSON A1_addBlacker(HttpServletRequest req, HttpServletResponse resp, Integer uid_target) {
		final int uid_this = SCUser.getUidFromReq(req);
		FollowsVo followsVo_this;
		int blackerCount_org;
		boolean isFriend_org; // 拉黑前,是否为好友

		// 参数基本检查:
		if (uid_target == null || uid_target < CUser.MIN_USER_ID) {
			return Message(ERROR, "目标用户id错误", null);
		}
		if (uid_target == uid_this) {
			return Message(ERROR, "不能自己拉黑自己", null);
		}

		followsVo_this = followsService.getFriendByIdAllStatus(uid_target, uid_this);
		// 检查自己是否已拉黑了对方:
		if (followsVo_this != null && followsVo_this.getSysflag() == 3) {
			return Message(SUCCESS, "已拉黑成功", null);
		}
		// 检查黑名单数量上限:
		zt.tb.function(); // 将用户的好友和黑名单数据缓存在内存中,直接在内存中检查
		blackerCount_org = followsService.getBlackCount(uid_this);
		if (blackerCount_org >= CUser.MAX_BLACKERS_COUNT) {
			return Message(ERROR, "黑名单人数已达上限", null);
		}

		// 临时记录拉黑前是否是好友:
		isFriend_org = false;
		if (followsVo_this != null && followsVo_this.getSysflag() == 0) {
			isFriend_org = true; // 拉黑前是好友
		}
		/////////////////////////// 至此,通过了所有检查,开始修改数据:
		if (followsVo_this == null) {
			followsVo_this = new FollowsVo();
			followsVo_this.setFollowed(uid_target);
			followsVo_this.setFollower(uid_this);
			// followsVo_this.setSysflag(3);
		}
		followsVo_this.setSysflag(3);
		followsService.saveFollows(followsVo_this);

		// 若拉黑前是好友,拉黑造成好友数量(以及对方的被关注数量)减一。需要维护关注和被关注的总计数:
		if (isFriend_org == true) {
			zt.tb.function(); // 将用户的好友数据缓存在内存中,去掉TotalInfoVo中的Follow字段和BeFollowed字段(不需要再维护了!)
			{
				TotalInfoVo t1 = totalInfoService.getInfoByUid(uid_this);
				t1.setFollow(t1.getFollow() - 1);
				TotalInfoVo t2 = totalInfoService.getInfoByUid(uid_target);
				t2.setBeFollowed(t2.getBeFollowed() - 1);
				totalInfoService.saveOrUpateInfo(t1);
				totalInfoService.saveOrUpateInfo(t2);
			}
		}
		// 通知第三方聊天平台,拉黑该用户(让第三方聊天平台,负责实现聊天过滤):
		boolean rt_chatAddBlack = ChatUtils.addBlackList(uid_this + "", new String[] { uid_target + "" });
		if (rt_chatAddBlack == false) {
			zt.tb.question(); // 处理第三方聊天平台,拉黑失败的情况?
			zt.print_doubt("ChatUtils.addBlackList exception:第三方聊天平台,拉黑失败?", null);
		}
		return Message(SUCCESS, "拉黑成功", null);
	}

	/**
	 * 加关注(添加好友)
	 * 
	 * @param req
	 * @param resp
	 * @param uid_target
	 *            被关注者(目标好友)id
	 * @return
	 */
	@RequestMapping("/addFriend")
	@ResponseBody
	public JSON A1_addFriend(HttpServletRequest req, HttpServletResponse resp, Integer uid_target) {
		final int uid_this = SCUser.getUidFromReq(req);
		FollowsVo followsVo_target, followsVo_this;
		int friendsCount_org;

		// 参数基本检查:
		if (uid_target == null || uid_target < CUser.MIN_USER_ID) {
			return Message(ERROR, "目标用户id错误", null);
		}
		if (uid_target == uid_this) {
			return Message(ERROR, "不能自己关注自己", null);
		}

		followsVo_this = followsService.getFriendByIdAllStatus(uid_target, uid_this);
		// 检查自己是否已关注了对方:
		if (followsVo_this != null && followsVo_this.getSysflag() == 0) {
			return Message(SUCCESS, "已关注成功", null);
		}
		// 检查好友数量上限:
		zt.tb.function(); // 将用户的好友数据缓存在内存中,直接在内存中检查
		friendsCount_org = followsService.getMyFollowsCount(uid_this);
		if (friendsCount_org >= CUser.MAX_FRIENDS_COUNT) {
			return Message(ERROR, "关注人数已达上限", null);
		}

		zt.td.question(); // 按照策划设计,即使对方已拉黑了自己,自己也还是可以正常关注对方。只是在评论/聊天时会被阻拦和提示。
		// // 检查对方是否已拉黑自己:
		// followsVo_target =
		// followsService.getFriendByIdAllStatus(uid_this, uid_target);
		// if (followsVo_target != null && followsVo_target.getSysflag() ==
		// 3) {
		// return Message(ERROR, "已被对方拉黑,无法关注该用户", null);
		// }

		/////////////////////// 至此,已通过了所有检查,开始修改数据:
		// 修改followsVo数据:
		if (followsVo_this == null) {
			followsVo_this = new FollowsVo();
			followsVo_this.setFollowed(uid_target);
			followsVo_this.setFollower(uid_this);
		}
		followsVo_this.setSysflag(0);
		followsService.saveFollows(followsVo_this);

		// 维护关注和被关注的总计数:
		zt.tb.function(); // 将用户的好友数据缓存在内存中,去掉TotalInfoVo中的Follow字段和BeFollowed字段(不需要再维护了!)
		{
			// 维护uid_this的TotalInfoVo的Follow字段:
			TotalInfoVo totalInfoVo_this = totalInfoService.getInfoByUid(uid_this);
			if (totalInfoVo_this == null) {
				totalInfoVo_this = new TotalInfoVo();
				totalInfoVo_this.setUid(uid_this);
				totalInfoVo_this.setFollow(1);
			} else {
				totalInfoVo_this.setFollow(totalInfoVo_this.getFollow() + 1);
			}
			totalInfoService.saveOrUpateInfo(totalInfoVo_this);
			// 维护uid_target的TotalInfoVo的BeFollowed字段:
			TotalInfoVo totalInfoVo_target = totalInfoService.getInfoByUid(uid_target);
			if (totalInfoVo_target == null) {
				totalInfoVo_target = new TotalInfoVo();
				totalInfoVo_target.setUid(uid_target);
				totalInfoVo_target.setFollow(0);
				totalInfoVo_target.setBeFollowed(1);
			} else {
				totalInfoVo_target.setBeFollowed(totalInfoVo_target.getBeFollowed() + 1);
			}
			totalInfoService.saveOrUpateInfo(totalInfoVo_target);
		}
		return Message(SUCCESS, "关注成功", null);
	}

	/**
	 * 加关注(添加好友)
	 * 
	 * @param req
	 * @param resp
	 * @param followed
	 *            被关注者
	 * @param follower
	 *            关注者
	 * @return
	 */
	@RequestMapping("/follows")
	@ResponseBody
	public JSON dep_follows(HttpServletRequest req, HttpServletResponse resp, Integer followed, Integer follower) {
		zt.ts.function(); // 待作废,用addFriend接口代替!
		try {
			if (followed == null && follower == null) {
				return Message(ERROR, "未提交用户id", null);
			}
			if (followed == follower) {
				return Message(ERROR, "这不是你自己吗？", null);
			}
			FollowsVo followCheck = followsService.getFriendByIdAllStatus(follower, followed);
			if (followCheck != null && followCheck.getSysflag() == 3) {
				return Message(ERROR, "当前无法关注该用户", null);
			}
			FollowsVo follow = followsService.getFriendByIdAllStatus(followed, follower);
			// 查询总的关注被关注信息
			TotalInfoVo total = totalInfoService.getInfoByUid(followed);
			if (total == null) {
				total = new TotalInfoVo();
				total.setUid(followed);
				total.setFollow(0);
				total.setBeFollowed(1);
			} else {
				total.setBeFollowed(total.getBeFollowed() + 1);
			}
			// 查询总的关注被关注信息
			TotalInfoVo total2 = totalInfoService.getInfoByUid(follower);
			if (total2 == null) {
				total2 = new TotalInfoVo();
				total2.setUid(follower);
				total2.setFollow(1);
			} else {
				total2.setFollow(total2.getFollow() + 1);
			}

			if (follow != null) {
				if (follow.getSysflag() == 3) { // 判断是否拉黑
					return Message(ERROR, "已拉黑账号无法关注", null);
				}
				if (follow.getSysflag() == 1) {
					follow.setSysflag(0);
					followsService.saveFollows(follow);
					totalInfoService.saveOrUpateInfo(total);
					totalInfoService.saveOrUpateInfo(total2);
					return Message(SUCCESS, "关注成功", null);
				}
				if (follow.getSysflag() == 0) {
					return Message(SUCCESS, "已关注成功", null);
				}
			} else {
				FollowsVo vo = new FollowsVo();
				vo.setFollowed(followed);
				vo.setFollower(follower);
				followsService.saveFollows(vo);
				totalInfoService.saveOrUpateInfo(total);
				totalInfoService.saveOrUpateInfo(total2);
				return Message(SUCCESS, "关注成功", null);
			}
		} catch (Exception e) {
			LoggerUtil.logInfo(e, "关注异常");
		}
		return null;
	}

	/**
	 * 取消关注接口
	 * 
	 * @param req
	 * @param resp
	 * @param followed
	 *            被关注的人
	 * @param follower
	 *            主动关注者
	 * @return
	 */
	@RequestMapping("/cancelFollowed")
	@ResponseBody
	public JSON dep_cancelFollowed(HttpServletRequest req, HttpServletResponse resp, Integer followed,
			Integer follower) {
		zt.ts.function(); // 待作废,用"cancelFriend"接口代替
		try {
			if (followed == null && follower == null) {
				return Message(ERROR, "未提交用户id", null);
			}
			FollowsVo vo = followsService.getFriendById(followed, follower, 0);
			if (vo == null) {
				return Message(ERROR, "不存在该关注", null);
			}
			vo.setSysflag(1);
			followsService.saveFollows(vo);
			TotalInfoVo total = totalInfoService.getInfoByUid(followed);
			total.setBeFollowed(total.getBeFollowed() - 1);
			TotalInfoVo total2 = totalInfoService.getInfoByUid(follower);
			total2.setFollow(total2.getFollow() - 1);
			totalInfoService.saveOrUpateInfo(total);
			totalInfoService.saveOrUpateInfo(total2);
			return Message(SUCCESS, "取消成功", null);
		} catch (Exception e) {
			LoggerUtil.logInfo(e, "取消异常");
		}
		return null;
	}

	/**
	 * 拉黑功能接口
	 * 
	 * @param req
	 * @param resp
	 * @param uid
	 *            用户id
	 * @param blacker
	 *            被拉黑者id
	 * @return
	 */
	@RequestMapping("/putBlack")
	@ResponseBody
	public JSON dep_putBlack(HttpServletRequest req, HttpServletResponse resp, Integer uid, Integer blacker) {
		zt.ts.function(); // 待作废,用接口"addBlacker"代替!
		if (uid == null) {
			return Message(ERROR, "未提交uid", null);
		}
		if (blacker == null) {
			return Message(ERROR, "未提交被拉黑者id", null);
		}
		FollowsVo follow = followsService.getFriendByIdAllStatus(blacker, uid);
		if (follow != null && follow.getSysflag() == 3) {
			follow.setSysflag(3);
			return Message(SUCCESS, "已拉黑好友", null);
		}
		if (follow != null && follow.getSysflag() != 3) {
			TotalInfoVo t1 = totalInfoService.getInfoByUid(uid);
			t1.setFollow(t1.getFollow() - 1);
			TotalInfoVo t2 = totalInfoService.getInfoByUid(blacker);
			t2.setBeFollowed(t2.getBeFollowed() - 1);
			totalInfoService.saveOrUpateInfo(t1);
			totalInfoService.saveOrUpateInfo(t2);
			follow.setSysflag(3);
		}
		if (follow == null) {
			follow = new FollowsVo();
			follow.setFollowed(uid);
			follow.setFollower(blacker);
			follow.setSysflag(3);
		}
		followsService.saveFollows(follow);
		String[] str = new String[1];
		str[0] = blacker + "";
		ChatUtils.addBlackList(uid + "", str);
		return Message(SUCCESS, "和你的小伙伴说再见吧", null);
	}

	/**
	 * 取消拉黑接口
	 * 
	 * @param req
	 * @param resp
	 * @param uid
	 *            用户id
	 * @param blacker
	 *            被拉黑者id
	 * @return
	 */
	@RequestMapping("/cancelBlack")
	@ResponseBody
	public JSON dep_cancelBlack(HttpServletRequest req, HttpServletResponse resp, Integer uid, Integer blacker) {
		zt.ts.function(); // 待作废,用cancelBlacker接口代替!
		if (uid == null) {
			return Message(ERROR, "未提交用户id", null);
		}
		if (blacker == null) {
			return Message(ERROR, "被拉黑者id", null);
		}
		FollowsVo follow = followsService.getFriendByIdAllStatus(blacker, uid);
		follow.setSysflag(1);
		followsService.saveFollows(follow);
		return Message(SUCCESS, "你的小伙伴恢复了自由", null);
	}

	/**
	 * 获取黑名单
	 * 
	 * @param req
	 * @param resp
	 * @param uid
	 *            用户id
	 * @return
	 */
	@RequestMapping("/getBlackList")
	@ResponseBody
	public JSON dep_getBlackList(HttpServletRequest req, HttpServletResponse resp, Integer uid) {
		zt.ts.function(); // 待作废,用"/Util/getBlackUsers"接口代替(接口实现:FriendsAction.A2_getBlackUsers())
		if (uid == null) {
			return Message(ERROR, "用户id为空", null);
		}
		List<FollowsVo> ls = followsService.getBlackList(uid);
		JSONArray array = new JSONArray();
		if (ls.size() > 0) {
			for (FollowsVo f : ls) {
				UserVo user = userService.getUserByKey(f.getFollowed());
				if (user != null) {
					JSONObject obj = new JSONObject();
					obj.put("nickName", user.getNickName());
					obj.put("uid", user.getId());
					obj.put("headUrl", isEmpty(user.getImgUrl()) ? null
							: oss.getUrl(bucket, user.getImgUrl(), new Date(new Date().getTime() + 3600 * 1000 * 12)));
					obj.put("sex", user.getSex());
					array.add(obj);
				}
			}
		}
		return Message(SUCCESS, "获取黑名单成功", array.size() > 0 ? array : null);
	}

	/**
	 * 检查两个用户是否关注中
	 * 
	 * @param req
	 * @param resp
	 * @param followed
	 *            被关注者id
	 * @param follower
	 *            关注者id
	 * @return
	 */
	@RequestMapping("/checkFollowed")
	@ResponseBody
	public JSON checkFollowed(HttpServletRequest req, HttpServletResponse resp, Integer followed, Integer follower) {
		zt.ts.question(); // 待作废。不能提供自由查询的接口,follower和followed至少应该有一个是用户自己。
		zt.ts.question(); // 需要通过客户端查询此接口的使用情况,再重构此接口(参见FriendsAction.A2_getAssociatedUsers)!

		if (followed == null || follower == null) {
			return Message(ERROR, "未提交完整用户id", null);
		}
		FollowsVo follow = null;
		follow = followsService.getFriendById(followed, follower, 0);
		if (follow == null) {
			return Message(SUCCESS, "查询消息成功", 1);
		} else {
			return Message(SUCCESS, "查询消息成功", 2);
		}
	}
}
